package com.hwh.springdatajpademo.service.impl;

import com.google.common.collect.Lists;
import com.hwh.springdatajpademo.pojo.DTO.UserDTO;
import com.hwh.springdatajpademo.pojo.DTO.UserRoleDTO;
import com.hwh.springdatajpademo.pojo.QRole;
import com.hwh.springdatajpademo.pojo.QUser;
import com.hwh.springdatajpademo.pojo.User;
import com.hwh.springdatajpademo.repository.UserRepository;
import com.hwh.springdatajpademo.service.UserService;
import com.querydsl.core.QueryResults;
import com.querydsl.core.types.ExpressionUtils;
import com.querydsl.core.types.Predicate;
import com.querydsl.jpa.impl.JPAQueryFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserRepository repository;
    @Autowired
    JPAQueryFactory factory;
    @Override
    public User findByNameAndEmail(String name, String email) {
        QUser user = QUser.user;
        return factory.selectFrom(user).where(
                user.name.eq(name),
                user.email.like(email)
        ).fetchOne();
    }

    @Override
    public List<User> findAllByNameOrderDesc() {
        QUser user = QUser.user;
        return factory
                .selectFrom(user)
                .orderBy(user.name.desc())
                .fetch();
    }

    @Override
    public QueryResults<User> findAllPage(Pageable pageable) {
        QUser user = QUser.user;
        return factory
                .selectFrom(user)
                .orderBy(user.name.desc())
                .offset(pageable.getOffset())
                .limit(pageable.getPageSize())
                .fetchResults();
    }

    @Override
    public List<UserDTO> findAllUserDTO(Pageable pageable) {
//        QUser user = QUser.user;
//        return factory.selectFrom(user)
//                .offset(pageable.getOffset())
//                .limit(pageable.getPageSize())
//                .fetch().stream().map(tuple ->
//                        UserDTO.builder()
//                                .name(tuple.getName())
//                                .id(tuple.getId())
//                                .email(tuple.getEmail()).build()
//                ).collect(Collectors.toList());
        return null;
    }

    @Override
    public List<User> findUserByPredicate(User user) {
        if (user == null){
            return null;
        }
        QUser quser = QUser.user;
        //初始化组装条件(类似where 1=1)
        Predicate predicate = quser.isNotNull().or(quser.isNull());

        predicate = user.getId() == null ? predicate : ExpressionUtils.and(predicate,quser.id.eq(user.getId()));
        predicate = user.getEmail() == null ? predicate : ExpressionUtils.and(predicate,quser.email.eq(user.getEmail()));
        predicate = user.getName() == null ? predicate : ExpressionUtils.and(predicate,quser.name.eq(user.getName()));
        Iterable<User> all = repository.findAll(predicate);
        List<User> list = Lists.newArrayList();
        all.forEach(list::add);
        return list;
    }

    @Override
    public List<UserRoleDTO> findAllByUserRoleDTO() {
//        QUser user = QUser.user;
//        QRole role = QRole.role;
//        return factory
//                .select(
//                        user.id,
//                        user.name,
//                        role.roleName
//                )
//                .from(user,role)
//                .where(role.id.eq(user.roleId))
//                .fetch()
//                .stream()
//                .map(tuple -> UserRoleDTO.builder()
//                        .name(tuple.get(user.name))
//                        .id(tuple.get(user.id))
//                        .roleName(tuple.get(role.roleName)).build()
//                ).collect(Collectors.toList());
        return null;
    }


}
